package channelService

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEnum/enumOperateMode"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisRpc"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisService"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Uuid"
	"net/http"
	"time"
)

type channelService struct {
}

func (e *channelService) exchange(deviceName string, send interface{}, timeout int) (interface{}, error) {
	// 进一步获取通道的详细信息
	deviceEntity := commRedisService.GetDeviceEntity(deviceName)
	if deviceEntity == nil {
		return nil, errors.New("在数据库找不到该设备实体：" + deviceName)
	}

	// 通道实体
	channelEntity := commRedisService.GetChannelEntity(deviceEntity.ChannelName, deviceEntity.ChannelType)
	if channelEntity == nil {
		return nil, errors.New("在数据库找不到该设备实体：" + deviceEntity.ChannelName)
	}

	requestVO := &commRedisRpc.ChannelRequestVO{}
	requestVO.Type = channelEntity.ChannelType
	requestVO.Mode = enumOperateMode.Exchange
	requestVO.Name = deviceEntity.ChannelName
	requestVO.Timeout = timeout
	requestVO.Send = send

	respondVO, err := e.executeChannel(requestVO)
	if err != nil {
		return nil, err
	}
	if respondVO == nil {
		return nil, err
	}
	if respondVO.Code != http.StatusOK {
		return nil, errors.New(respondVO.Msg)
	}

	return respondVO.Recv, nil
}

func (e *channelService) executeChannel(requestVO *commRedisRpc.ChannelRequestVO) (*commRedisRpc.ChannelRespondVO, error) {
	// 填写UID，从众多方便返回的数据中，识别出来对应的返回报文
	if requestVO.Uuid == "" {
		requestVO.Uuid = Uuid.RandomUUID()
	}

	// 发送数据
	commRedisRpc.Channel.Client.Request.Push(requestVO.Type, requestVO)

	// 等待数据
	respond, err := commRedisRpc.Channel.Client.Respond.Pop(requestVO.Type, requestVO.Uuid, time.Duration(requestVO.Timeout)*time.Millisecond)
	if err != nil {
		return nil, err
	}
	if respond == nil {
		return nil, errors.New("通道服务响应超时：" + requestVO.Type)
	}

	return respond, nil
}

func (e *channelService) publish(deviceName string, send interface{}, timeout int) error {
	// 进一步获取通道的详细信息
	deviceEntity := commRedisService.GetDeviceEntity(deviceName)
	if deviceEntity == nil {
		return errors.New("在数据库找不到该设备实体：" + deviceName)
	}

	// 通道实体
	channelEntity := commRedisService.GetChannelEntity(deviceEntity.ChannelName, deviceEntity.ChannelType)
	if channelEntity == nil {
		return errors.New("在数据库找不到该设备实体：" + channelEntity.ChannelName)
	}

	requestVO := &commRedisRpc.ChannelRequestVO{}
	requestVO.Type = channelEntity.ChannelType
	requestVO.Mode = enumOperateMode.Publish
	requestVO.Name = deviceEntity.ChannelName
	requestVO.Timeout = timeout
	requestVO.Send = send

	// 向非应答类型的设备发送请求
	err := e.publishChannel(requestVO)
	if err != nil {
		return err
	}

	return nil
}

func (e *channelService) publishChannel(requestVO *commRedisRpc.ChannelRequestVO) error {
	// 填写UID，从众多方便返回的数据中，识别出来对应的返回报文
	if requestVO.Uuid == "" {
		requestVO.Uuid = Uuid.RandomUUID()
	}

	// 发送数据
	commRedisRpc.Channel.Client.Request.Push(requestVO.Type, requestVO)

	// 等待数据
	respond, err := commRedisRpc.Channel.Client.Respond.Pop(requestVO.Type, requestVO.Uuid, time.Duration(requestVO.Timeout)*time.Millisecond)
	if err != nil {
		return err
	}
	if respond == nil {
		return errors.New("通道服务响应超时：" + requestVO.Type)
	}

	return nil
}
